package network;

import ihm.MainFrame;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;

import cipher.algorithm.A51;
import cipher.algorithm.Algorithm;
import cipher.algorithm.LFSR_1;
import cipher.module.Cipher_;
import cipher.module.Cipher_Thread_Manager;

import tools.BMPUtils;
import tools.TCPUtils;

//** Classe associee au traitement des commandes recues par le serveur **/
//** Elle est associe a un joueur, lui permettant de controler ses actions en fonction des demandes **/
public class KrakenCommandInterpreter {
	
	private KrakenThread krakenThread;

    private final Object lock = new Object(), lock2 = new Object();
	
	//* Methode d'interpretation des messages : on traite chaque message present dans RogueClientMsg */
	public KrakenCommandInterpreter(KrakenThread thread) {
		this.krakenThread = thread;
	}
	
	public void interpret(String msg) {
		String[] msgCmd;
		@SuppressWarnings("unused")
		String[] testSavedMessage;
		
		//System.out.println("KrakenCommandInterpreter: J'analyse : \""+msg+"\"");
		
		msgCmd = msg.split("  ");
		
		// identification Client-Serveur
		if(msgCmd[0].equalsIgnoreCase(KrakenClientMsg.CIPHER_CLIENT.toString())) {
			System.out.println("Je dois traiter KRAKEN_CLIENT");
			krakenThread.sendCommand(KrakenServerMsg.CIPHER_SERVER.makeCommand());
		}
		
		else if(msgCmd[0].equalsIgnoreCase(KrakenClientMsg.WAITING_NEXT_FRAME.toString())) {
			krakenThread.sendCommand(KrakenServerMsg.SEND_NEXT_FRAME.makeCommand());
		}
		
		// waiting flux
		else if(msgCmd[0].equalsIgnoreCase(KrakenClientMsg.WAITING_FLUX.toString())) {
			krakenThread.sendCommand(KrakenServerMsg.SEND_FLUX.makeCommand());
			String client_cmd = "";
			
			System.out.println("J'envois un flux de données");
			// nouvelle tache qui va chercher les images périodiquement
			final long intervals = 1000/10;
			/*TimerTask timerTask = new TimerTask() {
				@Override
				public void run() {*/
			while(true) {
				// tache
				/*synchronized (lock2) {
					if(krakenThread.getKrakenServer().getSendKey()){
						System.out.println("Envoi la clé !!!");
						ArrayList<String> tmp = krakenThread.getKrakenServer().getMainFrame().getInitKey();
						krakenThread.sendCommand(KrakenServerMsg.SEND_KEY.makeCommand(" "
								+tmp.get(0), " "+tmp.get(1)));
						
						krakenThread.getKrakenServer().setSendKey(false);
					}
				}*/
				krakenThread.sendCommand(KrakenServerMsg.SEND_DATA.makeCommand());
				try {
					krakenThread.getKrakenServer().getCapture().capture(false);
					byte[] tab = krakenThread.getKrakenServer().getCapture().getData();
					//byte[] tab2 = new byte[tab.length];
					
					synchronized (lock) {
						//System.out.print(tab[100000]+" ");
						tab = Cipher_.chiffrement(krakenThread.getKrakenServer().getAlgo(),
								tab,
								krakenThread.getKrakenServer().getMODE());
						
						/*Cipher_Thread_Manager ctm = new Cipher_Thread_Manager();
						tab2 = ctm.chiffrement(krakenThread.getKrakenServer().getAlgo(),
								tab,
								krakenThread.getKrakenServer().getMODE(),
								4);
						System.out.println(tab[15000]+" "+tab2[15000]);*/
					}
					
					TCPUtils.tcpSendBytes(krakenThread.getSocket(), tab);
				} catch (IOException e) {
					System.out.println("lost connection with the client");
					break;
				}
				
				// attend la prochaine commande du client
				try {
					client_cmd = krakenThread.getIn().readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				if(client_cmd.equals(KrakenClientMsg.END_CLIENT.toString())) {
					System.out.println("disconnecting the client");
					krakenThread.sendCommand(KrakenServerMsg.END_SERVER.makeCommand());
					krakenThread.getKrakenServer().getMainFrame().refreshServerInfos();
					krakenThread.setRunOff();
					break;
				}
				else if(client_cmd.equals(KrakenClientMsg.CLIENT_EXIT.toString())) {
					System.out.println("disconnecting the client");
					krakenThread.getKrakenServer().getMainFrame().refreshServerInfos();
					krakenThread.setRunOff();
					break;
				}
				
				/*if(client_cmd.equals(KrakenClientMsg.REINITIALISATION.toString())) {
					krakenThread.getKrakenServer().getMainFrame().refreshServerInfos();
					krakenThread.sendCommand(KrakenServerMsg.REINITIALISATION_CONFIRMED.makeCommand());
					try {
						client_cmd = krakenThread.getIn().readLine();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}*/
			}
				/*}
			};

			Timer timer = new Timer();
			timer.scheduleAtFixedRate(timerTask, 0, intervals);*/
		}
		
		// envoit de l'entête
		else if(msgCmd[0].equalsIgnoreCase(KrakenClientMsg.WAITING_HEADER.toString())) {
			krakenThread.sendCommand(KrakenServerMsg.SEND_HEADER.makeCommand());
			krakenThread.getKrakenServer().getCapture().capture(true);
			byte[] tab = krakenThread.getKrakenServer().getCapture().getHeader();
			System.out.println("J'envois l'entête type");
			try {
				TCPUtils.tcpSendBytes(krakenThread.getSocket(), tab);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		// envoit des données
		/*else if(msgCmd[0].equalsIgnoreCase(KrakenClientMsg.WAITING_DATA.toString())) {
			byte[] tab = krakenThread.getKrakenServer().getCapture().getData();
			System.out.println("J'envois une image");
			krakenThread.sendCommand(KrakenServerMsg.SEND_DATA.makeCommand());
			try {
				TCPUtils.tcpSendBytes(krakenThread.getSocket(), tab);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}*/
		
		// fin de la connexion
		else if(msgCmd[0].equalsIgnoreCase(KrakenClientMsg.END_CLIENT.toString())) {
			System.out.println("Fin de la connexion");
			krakenThread.sendCommand(KrakenServerMsg.END_SERVER.makeCommand());
			krakenThread.setRunOff(); //obligatoire pour arrêter le thread
		}
		
		//Commande inconnue
		else {
			krakenThread.sendCommand(KrakenServerMsg.UNKNOWN_COMMAND.makeCommand(msg));
		}

	}
	
}
